
#include <stdio.h>
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "main.h"

extern lua_State* L;

int vid_height = 0, vid_width = 0;

void vid_init(int width, int height, bool fullscreen)
{
	vid_width = width;
	vid_height = height;
	// SDL setup
	
	if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO))
		die("SDL_Init failed!");

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE,     8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,   8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,    8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,   8);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
	SDL_WM_SetCaption("Red Spiders", 0);

	int flags = SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0);
	if (!SDL_SetVideoMode(width, height, 32, flags))
		die("SDL_SetVideoMode failed!");

	SDL_WM_GrabInput(SDL_GRAB_ON);
	SDL_EventState(SDL_MOUSEMOTION, SDL_DISABLE);
	SDL_WarpMouse(vid_width/2,vid_height/2);
	SDL_ShowCursor(SDL_DISABLE);

	// GL setup

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45, (float)width / height, 0.1, 1000);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glViewport(0, 0, width, height);

	glEnable(GL_DEPTH_TEST);
	glDepthMask(1);

	glEnable(GL_CULL_FACE);

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glEnable(GL_LINE_SMOOTH);
	glLineWidth(1);
	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);

	glEnable(GL_LIGHTING);
	float amb[4] = {0.1,0.1,0.1,1};
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);

	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

	glPolygonOffset(1,1);

	glClearColor(0.8,0.8,1,0);
	glClearStencil(0);

	float fog[4] = {0.8,0.8,1,0};
	glEnable(GL_FOG);
	glFogfv(GL_FOG_COLOR, fog);
	glFogf(GL_FOG_MODE, GL_EXP2);
	glFogf(GL_FOG_DENSITY, 0.025);
}

float vid_now()
{
	return SDL_GetTicks() / 1000.0;
}

bool vid_events()
{
	SDL_Event evt;
	int top = lua_gettop(L);
	while (SDL_PollEvent(&evt))
	{
		switch (evt.type)
		{
		case SDL_KEYDOWN: case SDL_KEYUP:
			if (evt.key.keysym.sym == SDLK_F12) return false;

			lua_pushstring(L, evt.type == SDL_KEYDOWN ? "keydown" : "keyup");
			lua_rawget(L, LUA_GLOBALSINDEX);
			if (lua_isnil(L, -1)) break;

			lua_pushstring(L, SDL_GetKeyName(evt.key.keysym.sym));

			if (lua_pcall(L, 1, 0, 0))
				printf("%s\n", lua_tostring(L, -1));
			break;
		case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP:

			lua_pushstring(L, evt.type == SDL_MOUSEBUTTONDOWN ?
				"mousedown" : "mouseup");
			lua_rawget(L, LUA_GLOBALSINDEX);
			if (lua_isnil(L, -1)) break;

			lua_pushnumber(L, evt.button.button);

			if (lua_pcall(L, 1, 0, 0))
				printf("%s\n", lua_tostring(L, -1));
			
			break;
		case SDL_QUIT: return false;
		default:
			printf("event: %i\n", evt.type);
		}
		lua_settop(L, top);
	}

	int x,y;
	SDL_GetMouseState(&x,&y);
	SDL_WarpMouse(vid_width/2,vid_height/2);

	lua_pushstring(L, "mousemotion");
	lua_rawget(L, LUA_GLOBALSINDEX);
	if (!lua_isnil(L, -1))
	{
		lua_pushnumber(L, x - vid_width/2);
		lua_pushnumber(L, y - vid_height/2);
		if (lua_pcall(L, 2, 0, 0))
			printf("%s\n", lua_tostring(L, -1));
	}

	static float last = 0;
	float now = vid_now();
	float dt = now - last;
	last = now;

	top = lua_gettop(L);
	lua_pushstring(L, "tick");
	lua_rawget(L, LUA_GLOBALSINDEX);
	if (!lua_isnil(L, -1)) {
		lua_pushnumber(L, dt);
		lua_pushnumber(L, now);
		if (lua_pcall(L, 2, 0, 0))
			printf("%s\n", lua_tostring(L, -1));
	}
	lua_settop(L, top);
	return true;
}

void vid_clear()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void vid_flip()
{
	int err = glGetError();
	if (err) printf("glError: 0x%x\n", err);

	SDL_GL_SwapBuffers();
}

void vid_fini()
{
	SDL_Quit();
}

